package com.cenntro.repair.service.impl;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.RandomUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import com.cenntro.auth.mapper.SysSooidMapper;
import com.cenntro.auth.model.dbo.SysSooidDO;
import com.cenntro.common.base.BaseServiceImpl;
import com.cenntro.common.redis.IRedisService;
import com.cenntro.common.util.ConvertorUtils;
import com.cenntro.common.util.result.Result;
import com.cenntro.oss.mapper.DevDeviceStaticMapper;
import com.cenntro.oss.mapper.SysAgentMapper;
import com.cenntro.oss.model.dbo.DevDeviceStaticDO;
import com.cenntro.oss.model.dbo.SysAgentDO;
import com.cenntro.repair.common.RepairEnum;
import com.cenntro.repair.mapper.AfterRepairFormMapper;
import com.cenntro.repair.mapper.AfterRepairLogMapper;
import com.cenntro.repair.model.dbo.AfterRepairFormDO;
import com.cenntro.repair.model.dbo.AfterRepairLogDO;
import com.cenntro.repair.model.dbo.AfterRepairRefDO;
import com.cenntro.repair.model.qo.AfterRepairFormQO;
import com.cenntro.repair.model.vo.AfterRepairCompleteVO;
import com.cenntro.repair.model.vo.AfterRepairDetailsVO;
import com.cenntro.repair.model.vo.AfterRepairDynamicVO;
import com.cenntro.repair.model.vo.RepairFormVO;
import com.cenntro.repair.service.AfterRepairFormService;
import com.cenntro.repair.service.AfterRepairLogService;
import com.cenntro.repair.service.AfterRepairRefService;
import com.google.common.collect.ImmutableMap;

/**
 * <p>
 * 维修单 服务实现类
 * </p>
 *
 * @author 
 * @since 2019-07-10
 */
@Service
public class AfterRepairFormServiceImpl extends BaseServiceImpl<AfterRepairFormMapper>
        implements AfterRepairFormService {

    @Resource
    private AfterRepairLogService afterRepairLogService;

    @Resource
    private AfterRepairRefService afterRepairRefService;

    @Resource
    private IRedisService redisService;

    @Resource
    private AfterRepairFormMapper afterRepairFormMapper;

    @Resource
    private SysAgentMapper sysAgentMapper;

    @Resource
    private DevDeviceStaticMapper devDeviceStaticMapper;

    @Resource
    private AfterRepairLogMapper afterRepairLogMapper;

    /**
     * (非 Javadoc)
    * <p>Title: insert</p>
    * <p>Description: </p> 新增覆盖父类
    * 1、新增保修单 2 新增维修记录 3.新增保修单图片， 4 新增维修记录系统指派
    * @param t
    * @return
    * @see com.cenntro.common.base.BaseServiceImpl#insert(java.lang.Object)
     */
    @Transactional
    @Override
    public int insert(Object t) {
        // Subject subject = SecurityUtils.getSubject();
        // SysSooidDO user = (SysSooidDO) subject.getPrincipal();
        AfterRepairFormQO repairVO = (AfterRepairFormQO) t;
        // SysSooidDO user = this.getSysSooidDO(repairVO.getToken());
        AfterRepairFormDO afterRepairFormDO = ConvertorUtils.deepConvert(t, AfterRepairFormDO.class);
        // 新增维修单
        afterRepairFormDO.setCdt(new Date());
        afterRepairFormMapper.insert(afterRepairFormDO);
        // 增加报修记录
        AfterRepairLogDO afterRepairLog = new AfterRepairLogDO();
        afterRepairLog.setSooid(repairVO.getSooid());
        afterRepairLog.setRepairId(afterRepairFormDO.getRepairId());
        afterRepairLog.setStatus(RepairEnum.CREATE.getStatus());
        afterRepairLog.setCdt(new Date());
        afterRepairLog.setUrl(repairVO.getUrl());
        // afterRepairLog.setCreateUser(user.getId().toString());
        // afterRepairLog.setUserId(user.getId());
        afterRepairLogService.insert(afterRepairLog);
        // 新增报修附件包括图片
        // AfterRepairAnnexDO afterRepairAnnex = new AfterRepairAnnexDO();
        // afterRepairAnnex.setCdt(cdt);
        // afterRepairAnnex.setLogId(afterRepairLog.getLogId());
        // afterRepairAnnex.setUrl(repairVO.getUrl());
        // afterRepairAnnexService.insert(afterRepairAnnex);
        // 增加系统指派记录
        afterRepairLog.setStatus(RepairEnum.ASSIGN.getStatus());
        afterRepairLog.setCdt(new Date());
        // 随机去用户id
        AfterRepairRefDO afterRepairRef = new AfterRepairRefDO();
        // afterRepairRef.setAgentId(user.getAgentId());
        List<AfterRepairRefDO> refs = afterRepairRefService.selectPage(afterRepairRef);
        if (CollectionUtils.isNotEmpty(refs)) {
            int index = RandomUtils.nextInt(0, refs.size() - 1);
            Integer userId = refs.get(index).getSooid();
            afterRepairLog.setSooid(userId);   // 取随机用户
        }
        afterRepairLog.setCreateUser("admin");
        afterRepairLog.setUrl(null);
        afterRepairLog.setRemark(repairVO.getTitle());
        afterRepairLogService.insert(afterRepairLog);
        return afterRepairFormDO.getRepairId();
    }

    @Transactional
    public int update(Object t) {
        AfterRepairFormQO repairVO = ConvertorUtils.deepConvert(t, AfterRepairFormQO.class);
        AfterRepairFormDO afterRepairFormDO = ConvertorUtils.deepConvert(t, AfterRepairFormDO.class);
        int i = afterRepairFormMapper.update(afterRepairFormDO);
        SysSooidDO user = this.getSooidDO(repairVO.getSooid());
        // 增加报修记录
        AfterRepairLogDO afterRepairLog = new AfterRepairLogDO();
        afterRepairLog.setRepairId(afterRepairFormDO.getRepairId());
        afterRepairLog.setStatus(RepairEnum.REPAIRING.getStatus());
        afterRepairLog.setCdt(new Date());
        afterRepairLog.setName(user.getRealName());
        afterRepairLog.setSooid(user.getId());
        afterRepairLogService.insert(afterRepairLog);
        return i;
    }

    /**
    * 
    * @Title updateComplete
    * @Description 维修完成
    * @param 
    * @return
    */
    public Result updateComplete(AfterRepairCompleteVO compVO) {
        AfterRepairFormDO afterRepairFormDO = new AfterRepairFormDO();
        afterRepairFormDO.setRepairId(compVO.getRepairId());
        afterRepairFormDO.setStatus(RepairEnum.COMPLETE.getStatus());
        // 增加完成内容表
        // AfterRepairCompleteDO comDO = new AfterRepairCompleteDO();
        afterRepairFormDO.setCarno(compVO.getCarno());
        afterRepairFormDO.setDevId(compVO.getDevId());
        afterRepairFormDO.setRepairMethod(compVO.getRepairMethod());
        afterRepairFormDO.setFaultClassification(compVO.getFaultClassification());
        afterRepairFormDO.setRepairPart(compVO.getRepairPart());
        this.update(afterRepairFormDO);
        // afterRepairCompleteService.insert(comDO);
        afterRepairFormMapper.update(afterRepairFormDO);
        // afterRepairCompleteService.insert(comDO);
        // 增加动态
        SysSooidDO user = this.getSooidDO(compVO.getSooid());
        AfterRepairLogDO afterRepairLog = new AfterRepairLogDO();
        afterRepairLog.setRepairId(afterRepairFormDO.getRepairId());
        afterRepairLog.setStatus(RepairEnum.COMPLETE.getStatus());
        afterRepairLog.setCdt(new Date());
        // afterRepairLog.setCreateUser(user.getnam);
        afterRepairLog.setSooid(user.getId());
        afterRepairLogService.insert(afterRepairLog);
        return Result.ok();
    }

    /**
     * 
    * @Title updateAssign
    * @Description 维修指派
    * @param 
    * @return
     */
    public Result updateAssign(AfterRepairFormQO repairVO) {
        AfterRepairFormDO afterRepairFormDO = new AfterRepairFormDO();
        afterRepairFormDO.setRepairId(repairVO.getRepairId());
        afterRepairFormDO.setStatus(RepairEnum.TRANSFER.getStatus());
        afterRepairFormMapper.update(afterRepairFormDO);
        // 增加动态
        SysSooidDO user = this.getSooidDO(repairVO.getSooid());
        AfterRepairLogDO afterRepairLog = new AfterRepairLogDO();
        afterRepairLog.setRepairId(afterRepairFormDO.getRepairId());
        afterRepairLog.setStatus(RepairEnum.TRANSFER.getStatus());
        afterRepairLog.setCdt(new Date());
        // afterRepairLog.setCreateUser(user.getId().toString());
        afterRepairLog.setSooid(user.getId());
        afterRepairLog.setName(user.getRealName());
        afterRepairLogService.insert(afterRepairLog);
        return Result.ok();
    }

    /**
     * 获取登录用户信息
    * @Title getSysSooidDO
    * @Description 
    * @param 
    * @return
     */
    // private SysSooidDO getSysSooidDO(String token) {
    // String key = KeyUtil.keyOf(keyEnum.USER_OSS, token);
    // SysSooidDO soo = redisService.getObject(key, SysSooidDO.class);
    // return soo;
    // }
    /**
     * 获取登录用户信息
    * @Title getSysSooidDO
    * @Description 
    * @param 
    * @return
    * 
     */
    @Resource
    private SysSooidMapper sysSooidMapper;

    private SysSooidDO getSooidDO(Integer sooid) {
        SysSooidDO soo = redisService.get("syssooid:" + sooid, SysSooidDO.class);
        if (soo == null) {
            soo = sysSooidMapper.selectById(sooid);
            Assert.isTrue(soo != null, "账号为空");
            redisService.set("syssooid:" + sooid, soo, 5000);
        }
        return soo;
    }

    /*
     * (非 Javadoc) <p>Title: details</p> <p>Description: </p>
     * 
     * @param repairId
     * 
     * @return
     * 
     * @see com.cenntro.repair.service.AfterRepairFormService#details(java.lang.
     * Integer)
     */
    @Override
    public AfterRepairDetailsVO details(Integer repairId) {
        AfterRepairDetailsVO vo = new AfterRepairDetailsVO();
        AfterRepairFormDO form = afterRepairFormMapper.selectById(repairId);
        vo.setRepairId(repairId);
        vo.setStatus(form.getStatus());
        vo.setRepairLevel(form.getRepairLevel());
        vo.setCarNo(form.getCarno());
        DevDeviceStaticDO DevDeviceStaticDO = devDeviceStaticMapper.selectById(form.getDevId());
        SysAgentDO sysAgent = sysAgentMapper.selectById(DevDeviceStaticDO.getAgentId());
        vo.setCompany(sysAgent.getCompany());
        vo.setTitle(form.getTitle());
        // vo.setBFiles(bFiles);
        // vo.setBTime(bTime);
        // vo.setBName(bName);
        // vo.setBTelephone(bTelephone);
        // vo.setWName(wName);
        // vo.setWTelephone(wTelephone);
        // vo.setFaultClassification(faultClassification);
        // vo.setRepairMethod(repairMethod);
        // vo.setWFiles(wFiles);
        // vo.setRepairPart(repairPart);
        if (form != null) {
            vo.setRepairId(repairId);
            vo.setStatus(form.getStatus());
            vo.setRepairLevel(form.getRepairLevel());
            vo.setCarNo(form.getCarno());
            vo.setCompany(sysAgent.getCompany());
            vo.setTitle(form.getTitle());
            AfterRepairLogDO afterRepairLog = afterRepairLogMapper
                    .selectOne(ImmutableMap.of("status", RepairEnum.CREATE.getStatus(), "repairId", repairId));
            vo.setBFiles(afterRepairLog.getUrl());
            vo.setBTime(new SimpleDateFormat("YYYY-MM-dd HH:mm:ss").format(afterRepairLog.getCdt()));
            SysSooidDO sooid = sysSooidMapper.selectById(afterRepairLog.getSooid());
            if (sooid != null) {
                vo.setBName(sooid.getRealName());
                vo.setBTelephone(sooid.getTelephone());
            }
            afterRepairLog = afterRepairLogMapper
                    .selectOne(ImmutableMap.of("status", RepairEnum.COMPLETE.getStatus(), "repairId", repairId));
            if (afterRepairLog != null) {
                sooid = sysSooidMapper.selectById(afterRepairLog.getSooid());
                if (sooid != null) {
                    vo.setWName(sooid.getRealName());
                    vo.setWTelephone(sooid.getTelephone());
                }
                vo.setWFiles(afterRepairLog.getUrl());
            }
            vo.setFaultClassification(form.getFaultClassification());
            vo.setRepairMethod(form.getRepairMethod());
            vo.setRepairPart(form.getRepairPart());
        }
        return vo;
    }

    @Override
    public List<RepairFormVO> selectByDevId(Integer devId) {
        List<AfterRepairFormDO> formDOList = afterRepairFormMapper.selectByDevId(devId);
        List<RepairFormVO> convertList = ConvertorUtils.deepConvertList(formDOList, RepairFormVO.class);
        return convertList;
    }

    /*
     * (非 Javadoc) <p>Title: dynamic</p> <p>Description: </p>
     * 
     * @param repairId
     * 
     * @return
     * 
     * @see com.cenntro.repair.service.AfterRepairFormService#dynamic(java.lang.
     * Integer)
     */
    @Override
    public List<AfterRepairDynamicVO> dynamic(Integer repairId) {
        List<AfterRepairDynamicVO> dynamic = new ArrayList<AfterRepairDynamicVO>();
        List<AfterRepairLogDO> list = afterRepairLogMapper.selectPage(ImmutableMap.of("repairId", repairId));
        SysSooidDO sooid = new SysSooidDO();
        if (CollectionUtils.isNotEmpty(list)) {
            List<Integer> listStatus = Arrays.asList(RepairEnum.CREATE.getStatus(), RepairEnum.REPAIRING.getStatus(),
                    RepairEnum.COMPLETE.getStatus(), RepairEnum.CANCEL.getStatus());
            for (int i = 0; i < list.size(); i++) {
                AfterRepairLogDO log = list.get(i);
                AfterRepairDynamicVO vo = new AfterRepairDynamicVO();
                // 报维修单 // 开始维修 // 完成 // 撤销
                // if
                // (RepairEnum.CREATE.getStatus().equals(log.getStatus())||RepairEnum.REPAIRING.getStatus().equals(log.getStatus())||RepairEnum.COMPLETE.getStatus().equals(log.getStatus())||RepairEnum.CANCEL.getStatus().equals(log.getStatus()))
                // {
                if (listStatus.contains(log.getStatus())) {
                    sooid = getSooidDO(log.getSooid());
                    vo.setName(sooid.getRealName());
                    vo.setTelphone(sooid.getTelephone());
                }
                // 系统指派
                if (RepairEnum.ASSIGN.getStatus().equals(log.getStatus())) {
                    sooid = getSooidDO(log.getSooid());
                    vo.setName("系统");
                    vo.setToName(sooid.getRealName());
                    vo.setToTelphone(sooid.getTelephone());
                }
                // 开始维修
                // if (RepairEnum.REPAIRING.getStatus().equals(log.getStatus()))
                // {
                // sooid = getSooidDO(log.getSooid());
                // vo.setName(sooid.getRealName());
                // vo.setTelphone(sooid.getTelephone());
                // }
                // 转单
                if (RepairEnum.TRANSFER.getStatus().equals(log.getStatus())) {
                    sooid = getSooidDO(log.getSooid());
                    vo.setToName(sooid.getRealName());
                    vo.setToTelphone(sooid.getTelephone());
                    AfterRepairLogDO afterRepairLogDO = list.get(i - 1);
                    sooid = getSooidDO(afterRepairLogDO.getSooid());
                    vo.setName(sooid.getRealName());
                    vo.setTelphone(sooid.getTelephone());
                }
                // 完成
                // if (RepairEnum.COMPLETE.getStatus().equals(log.getStatus()))
                // {
                // sooid = getSooidDO(log.getSooid());
                // vo.setName(sooid.getRealName());
                // vo.setTelphone(sooid.getTelephone());
                // }
                // 撤销
                // if (RepairEnum.CANCEL.getStatus().equals(log.getStatus())) {
                // sooid = getSooidDO(log.getSooid());
                // vo.setName(sooid.getRealName());
                // vo.setTelphone(sooid.getTelephone());
                // }
                vo.setStatus(log.getStatus());
                vo.setTitle(log.getRemark());
                dynamic.add(vo);
            }
        }
        Collections.sort(dynamic, new Comparator<AfterRepairDynamicVO>() {

            public int compare(AfterRepairDynamicVO vo1, AfterRepairDynamicVO vo2) {
                return vo2.getStatus().compareTo(vo1.getStatus());
            };
        });
        return dynamic;
    }
}
